package cn.edu.usst.cs.goldfish.booking.meetingroom.web.controller;

import cn.edu.usst.cs.goldfish.booking.meetingroom.model.Meeting;
import cn.edu.usst.cs.goldfish.booking.meetingroom.model.MeetingAttendee;
import cn.edu.usst.cs.goldfish.booking.meetingroom.model.MeetingSlot;
import cn.edu.usst.cs.goldfish.booking.meetingroom.model.SysUser;
import cn.edu.usst.cs.goldfish.booking.meetingroom.mybatis.MeetingAttendeeMapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.mybatis.MeetingMapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.mybatis.MeetingSlotMapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.mybatis.UserMapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.web.SessionKeys;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/api/notify")
public class NotificationController {
    private final UserMapper userMapper;
    private final MeetingMapper meetingMapper;
    private final MeetingSlotMapper meetingSlotMapper;
    private final MeetingAttendeeMapper meetingAttendeeMapper;

    public NotificationController(UserMapper userMapper, MeetingMapper meetingMapper, MeetingSlotMapper meetingSlotMapper, MeetingAttendeeMapper meetingAttendeeMapper) {
        this.userMapper = userMapper;
        this.meetingMapper = meetingMapper;
        this.meetingSlotMapper = meetingSlotMapper;
        this.meetingAttendeeMapper = meetingAttendeeMapper;
    }

    @GetMapping("/pull")
    public List<Map<String, Object>> pullNotifications(@SessionAttribute(SessionKeys.EMAIL) String email) {
        Long userId = userMapper.selectOne(new QueryWrapper<SysUser>().eq("email", email)).getId();
        List<Meeting> meetings = meetingMapper.selectList(
                new QueryWrapper<Meeting>().eq("organizer_id", userId)
        );
        List<MeetingAttendee> meetingAttendees
                = meetingAttendeeMapper
                .selectList(
                        new QueryWrapper<MeetingAttendee>().eq("user_id", userId)
                );

        List<Meeting> attendedMeetings = new ArrayList<>();
        for (MeetingAttendee meetingAttendee : meetingAttendees) {
            attendedMeetings.add(meetingMapper.selectOne(
                    new QueryWrapper<Meeting>().eq("meeting_id", meetingAttendee.getMeetingId())
            ));
        }
        List<Map<String, Object>> result = new ArrayList<>();
//        for (Meeting meeting : meetings) {
//            if (notAccompaniedByValidSlot(meeting)) continue;
//            Map<String, Object> map = getBAsicInfoMap(meeting);
//            map.put("role", "主办方");
//            result.add(map);
//        }
        for (Meeting meeting : attendedMeetings) {
            if (notAccompaniedByValidSlot(meeting)) continue;
            Map<String, Object> map = getBAsicInfoMap(meeting);
//            map.put("role", "参会者");
            result.add(map);
        }

        return result;

    }

    private boolean notAccompaniedByValidSlot(Meeting meeting) {
        List<MeetingSlot> slots = meetingSlotMapper.selectList(
                new QueryWrapper<MeetingSlot>().eq("meeting_id", meeting.getId())
        );
        Optional<MeetingSlot> startSlot = slots.stream()
                .min(Comparator.comparing(MeetingSlot::getTime));
        if (startSlot.isEmpty()) return true;
        if (startSlot.get().getTime().isBefore(LocalDateTime.now().minusDays(1))) {
            return true;
        }
        if (startSlot.get().getTime().isAfter(LocalDateTime.now())) {
            return true;
        }
        return false;
    }

    @NotNull
    private Map<String, Object> getBAsicInfoMap(Meeting meeting) {
        Map<String, Object> map = new HashMap<>();
        map.put("meetingId", meeting.getId());
        map.put("topic", meeting.getTopic());
        List<MeetingSlot> meetingSlots = meetingSlotMapper.selectList(
                new QueryWrapper<MeetingSlot>().eq("meeting_id", meeting.getId())
        );
        meetingSlots.stream()
                .min(Comparator.comparing(MeetingSlot::getTime))
                .ifPresent(
                        meetingSlot ->
                                map.put("time", meetingSlot.getTime())
                )
        ;
        return map;
    }
} 